package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.mapper.BlackMapper;
import com.tanhua.common.mapper.QuestionMapper;
import com.tanhua.common.mapper.SettingMapper;
import com.tanhua.common.pojo.*;
import com.tanhua.common.utils.TypeEnum;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.dubbo.server.api.HuanXinApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.pojo.Visitors;
import com.tanhua.dubbo.server.vo.PageInfo;
import com.tanhua.server.paramPojo.NotificationBo;
import com.tanhua.server.paramPojo.UpdateUserInfoBo;
import com.tanhua.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author feihao
 * @version 1.0
 * @date 2021/7/5 21:34
 */

@Service
@Slf4j
public class MyCenterService {

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private QuestionMapper questionMapper;

    @Value("${tanhua.sso.url}")
    private String ssoUrl;

    @Autowired
    private SettingMapper settingMapper;

    @Autowired
    private TanHuaService tanHuaService;

    @Autowired
    private BlackMapper blackMapper;


    @Reference(version = "1.0.0")
    private HuanXinApi huanXinApi;

    @Autowired
    private IMService imService;

    @Reference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @Autowired
    private RecommendUserService recommendUserService;


    @Reference(version = "1.0.0")
    private UserLikeApi userLikeApi;

    public UserInfoVo queryUserInfoByUserId(Long userId) {
        if (ObjectUtil.isEmpty(userId)) {
            //如果查询id为null，就表示查询当前用户信息
            userId = UserThreadLocal.get().getId();
        }
        //查询用户信息
        UserInfo userInfo = this.userInfoService.queryTodayBestInfo(userId);
        if (ObjectUtil.isEmpty(userInfo)) {
            return null;
        }

        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class, "marriage");
        userInfoVo.setGender(userInfo.getSex().name().toLowerCase());
        userInfoVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
        return userInfoVo;
    }


    public Boolean updateUserInfo(UpdateUserInfoBo updateUserInfoBo) {
        //获取要修改更新的用户：
        User user = UserThreadLocal.get();
        //填充要更新的字段：
        UserInfo userInfo = new UserInfo();
        userInfo.setSex(updateUserInfoBo.getGender().equals("man") ? SexEnum.MAN : SexEnum.WOMAN);
        userInfo.setUserId(user.getId());
        userInfo.setNickName(updateUserInfoBo.getNickname());
        userInfo.setBirthday(updateUserInfoBo.getBirthday());
        userInfo.setCity(updateUserInfoBo.getCity());
        userInfo.setEdu(updateUserInfoBo.getEducation());
        userInfo.setIncome(updateUserInfoBo.getIncome());
        userInfo.setIndustry(updateUserInfoBo.getProfession());
        userInfo.setMarriage(updateUserInfoBo.getMarriage().equals(0) ? "未婚" : "已婚");
        return userInfoService.updateUserInfo(userInfo);
    }


    /**
     * 转发请求到sso进行头像上传。
     *
     * @param multipartFile
     * @param token
     * @return
     */
    public ResponseEntity<Object> saveHeadPhoto(MultipartFile multipartFile, String token) throws IOException {
        String url = ssoUrl + "/user/loginReginfo/head";
        File file = new File(multipartFile.getOriginalFilename());
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);

        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(mediaType);
        headers.set("Authorization", token);

        //设置请求体，注意是LinkedMultiValueMap
        FileSystemResource fileSystemResource = new FileSystemResource(file);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("headPhoto", fileSystemResource);

        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(form, headers);

        ResponseEntity<Object> responseEntity = restTemplate.postForEntity(url, httpEntity, Object.class);
        //得删除文件，项目的根目录下。
        file.delete();
        return responseEntity;
    }


    /**
     * 设置更新问题或添加问题：
     *
     * @param content
     * @return
     */
    public Boolean updateOrSaveQuestion(String content) {
        User user = UserThreadLocal.get();
        Long userId = user.getId();
        //首相查询是否有设置问题：设置过则修改，没有则添加
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        Integer count = questionMapper.selectCount(queryWrapper);

        //设置问题对象：
        Question question = new Question();
        question.setTxt(content);
        question.setUserId(userId);

        if (count > 0) {
            //有设置过，直接更新：
            UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("user_id", userId);
            int update = questionMapper.update(question, updateWrapper);
            return update > 0;
        }
        if (count == 0) {
            //没有设置过：
            int insert = questionMapper.insert(question);
            return insert > 0;
        }
        return false;
    }


    /**
     * 查询设置 返回：
     *
     * @return
     */
    public SettingsVo querySettings() {
        User user = UserThreadLocal.get();

        QueryWrapper<Settings> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getId());
        Settings settings = settingMapper.selectOne(queryWrapper);

        if (ObjectUtil.isEmpty(settings)) {

            //设置默认设置：
            settings = new Settings();
            settings.setUserId(user.getId());
            settings.setGonggaoNotification(true);
            settings.setLikeNotification(true);
            settings.setPinglunNotification(true);

            settingMapper.insert(settings);
        }

        //封装SettingsVo：
        SettingsVo settingsVo = new SettingsVo();
        settingsVo.setId(settings.getId().intValue());
        settingsVo.setGonggaoNotification(settings.getGonggaoNotification());
        settingsVo.setLikeNotification(settings.getLikeNotification());
        settingsVo.setPinglunNotification(settings.getPinglunNotification());
        settingsVo.setPhone(user.getMobile());

        //查询问题表：
        /*QueryWrapper<Question> questionQueryWrapper = new QueryWrapper<>();
        questionQueryWrapper.eq("user_id", user.getId());
        Question question = questionMapper.selectOne(questionQueryWrapper);

        if (ObjectUtil.isEmpty(question)){
            settingsVo.setStrangerQuestion("没有设置问题！");
        }*/


        settingsVo.setStrangerQuestion(tanHuaService.findQuestion(user.getId()));


        return settingsVo;
    }


    /**
     * 保存通知设置：
     *
     * @param notificationBo
     * @return
     */
    public Boolean saveNotifications(NotificationBo notificationBo) {

        User user = UserThreadLocal.get();

        Settings settings = new Settings();
        settings.setPinglunNotification(notificationBo.getPinglunNotification());
        settings.setLikeNotification(notificationBo.getLikeNotification());
        settings.setGonggaoNotification(notificationBo.getGonggaoNotification());

        UpdateWrapper<Settings> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", user.getId());
        int update = settingMapper.update(settings, updateWrapper);

        return update > 0;
    }


    /**
     * 查询黑名单列表返回：
     *
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryBlackList(Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        User user = UserThreadLocal.get();

        //分页查询黑名单列表page：
        QueryWrapper<Black> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getId());
        queryWrapper.orderByDesc("created");
        Page<Black> iPage = new Page<>(page, pageSize);
        IPage<Black> blackIPage = blackMapper.selectPage(iPage, queryWrapper);

        //黑名单List:
        List<Black> blackList = blackIPage.getRecords();
        if (blackList.size() == 0) {
            return null;
        }

        //根据返回的blackUserId查询userInfo:
        List<Object> ids = new ArrayList<>();
        for (Black black : blackList) {
            ids.add(black.getBlackUserId());
        }

        List<UserInfo> userInfos = userInfoService.queryUserInfoByUserIdList(ids);
        //构造userId 与userInfo的map键值对：
        Map<Long, UserInfo> map = new HashMap<>();
        for (UserInfo userInfo : userInfos) {
            map.put(userInfo.getUserId(), userInfo);
        }

        //不为空：填充字段返回：
        BlackUserVo blackUserVo = null;
        List<BlackUserVo> blackUserVos = new ArrayList<>();
        for (Black black : blackList) {
            blackUserVo = new BlackUserVo();
            blackUserVo.setId(black.getBlackUserId());  //注意返回的id为black的userId
            blackUserVo.setAge(map.get(black.getBlackUserId()).getAge());
            blackUserVo.setAvatar(map.get(black.getBlackUserId()).getLogo());
            blackUserVo.setGender(map.get(black.getBlackUserId()).getSex().name());
            blackUserVo.setNickname(map.get(black.getBlackUserId()).getNickName());
            blackUserVos.add(blackUserVo);
        }

        pageResult.setItems(blackUserVos);

        return pageResult;
    }


    /**
     * 移除黑名单
     *
     * @param blackUserId
     * @return
     */
    public Boolean deleteBlackUser(Long blackUserId) {

        //获取当前用户：
        User user = UserThreadLocal.get();

        QueryWrapper<Black> wrapper = new QueryWrapper<>();
        wrapper.eq("black_user_id", blackUserId);
        wrapper.eq("user_id", user.getId());
        int delete = blackMapper.delete(wrapper);
        return delete > 0;

    }


    /**
     * 查询粉丝、喜欢、互相喜欢的数量：
     *
     * @return
     */
    public Map<String, Integer> getCounts() {
        User user = UserThreadLocal.get();

        Map<String, Integer> mapCounts = new HashMap<>();

        //喜欢的人数：
        List<Long> longList = userLikeApi.queryLikeList(user.getId());

        //互相喜欢数：
        int countEachLike = userLikeApi.queryEachLLikeCount(user.getId());

        //：粉丝数：
        int countFans = userLikeApi.queryFanCount(user.getId());

        mapCounts.put("loveCount", longList.size());
        mapCounts.put("eachLoveCount", countEachLike);
        mapCounts.put("fanCount", countFans);

        return mapCounts;
    }


    /**
     * 根据type返回对应的查询列表：1 互相关注  2 我关注   3 粉丝    4 谁看过我
     *
     * @param type
     * @return
     */
    public PageResult queryFriendList(TypeEnum type, Integer page, Integer pageSize, String nickname) {

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        User user = UserThreadLocal.get();
        Long userId = user.getId();

        List<Object> userIdsList = null;
        //判断：
        switch (type) {
            case EACH_LOVE: {
                //查询互相喜欢的列表的
                PageInfo<UserLike> pageInfo = userLikeApi.queryMutualLikeList(userId, page, pageSize);
                //互相喜欢的好友的idList
                userIdsList = CollUtil.getFieldValues(pageInfo.getRecords(), "userId");
                break;
            }
            case I_LIKE: {
                //查询我关注的列表的:获取关注的人的ids
                PageInfo<UserLike> pageInfo = userLikeApi.queryLikeList(userId, page, pageSize);
                userIdsList = CollUtil.getFieldValues(pageInfo.getRecords(), "likeUserId");
                break;
            }
            case FANS: {
                //查询粉丝列表的
                PageInfo<UserLike> pageInfo = userLikeApi.queryFanList(userId, page, pageSize);
                userIdsList = CollUtil.getFieldValues(pageInfo.getRecords(), "userId");
                break;
            }
            case WHO_LOOK_ME: {
                //查询访客列表的
                PageInfo<Visitors> pageInfo = visitorsApi.findVisitorsList(userId, page, pageSize);
                userIdsList = CollUtil.getFieldValues(pageInfo.getRecords(), "visitorUserId");
                break;
            }
            default:
                break;
        }

        if (userIdsList.size() == 0) {
            //直接返回pageResult;
            return pageResult;
        }

        //根据ids查询用户的详细信息：
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id", userIdsList);
        if (StrUtil.isNotEmpty(nickname)) {
            queryWrapper.like("nick_name", nickname);
        }

        List<UserInfo> userInfoList = this.userInfoService.queryRecommendationUserInfo(queryWrapper);

        //封装返回体：
        List<UserLikeListVo> likeListVos = new ArrayList<>();

        UserLikeListVo userLikeListVo = null;
        for (UserInfo userInfo : userInfoList) {
            userLikeListVo = new UserLikeListVo();

            userLikeListVo.setAge(userInfo.getAge());
            userLikeListVo.setAvatar(userInfo.getLogo());
            userLikeListVo.setCity(userInfo.getCity());
            userLikeListVo.setEducation(userInfo.getEdu());
            userLikeListVo.setGender(userInfo.getSex().name().toLowerCase());
            userLikeListVo.setId(userInfo.getUserId());
            userLikeListVo.setMarriage(StringUtils.equals(userInfo.getMarriage(), "已婚") ? 1 : 0);
            userLikeListVo.setNickname(userInfo.getNickName());
            //是否喜欢  userLikeApi中的isLike开放出来(私有方法变接口)
            userLikeListVo.setAlreadyLove(userLikeApi.isLike(userId, userInfo.getUserId()));


            Double score = this.recommendUserService.queryScore(userId, userInfo.getUserId());
            userLikeListVo.setMatchRate(Convert.toInt(score));

            likeListVos.add(userLikeListVo);
        }

        pageResult.setItems(likeListVos);

        return pageResult;
    }


    /**
     * 根据好友id,删除好友：
     *
     * @param deleteUserId
     * @return
     */
    public Boolean deleteLikeUserById(Long deleteUserId) {

        User user = UserThreadLocal.get();

        //首相判断是否互相喜欢：是的话就要删除环信好友关系：不是的话，只是移除userLike表：

        Boolean mutualLike = userLikeApi.isMutualLike(user.getId(), deleteUserId);

        //删除userLike表的喜欢内容：
        Boolean result = userLikeApi.notLikeUser(user.getId(), deleteUserId);

        Boolean huanXinResult = null;
        if (mutualLike) {
            //删除环信好友关系：
            imService.deleteUser(user.getId(), deleteUserId);
        }
        return result;
    }

    /**
     * 喜欢粉丝： 直接注册环信好友和添加userLike表：
     *
     * @param likeFansId
     * @return
     */
    public Boolean likeFansById(Long likeFansId) {

        User user = UserThreadLocal.get();

        Boolean aBoolean = userLikeApi.likeUser(user.getId(), likeFansId);

        //注册环信好友：因为已经是粉丝了，我再喜欢粉丝就直接是互相喜欢。直接注册：
        huanXinApi.addFriends(user.getId(), likeFansId);
        return aBoolean;
    }


    /**
     * 判断 主页用户是否已经喜欢：
     *
     * @param userId
     * @return
     */
    public Boolean isLike(Integer userId) {

        User user = UserThreadLocal.get();

        Boolean isLike = userLikeApi.isLike(user.getId(), Long.valueOf(userId));
        return isLike;
    }
}
